%{
#include "frontend.h"

#include "y.tab.h"

/* handle locations */
int yycolumn = 1;

char* cur_file;

#define YY_USER_ACTION yylloc.first_line = yylloc.last_line = yylineno; \
    yylloc.first_column = yycolumn; yylloc.last_column = yycolumn + yyleng - 1; \
    yycolumn += yyleng; \
	yylloc.file_name = cur_file;
%}
%option yylineno
%option noyywrap
%x LINECOMMENT BLOCKCOMMENT QUOTE

letter	[a-zA-Z]
digit	[0-9]
number	[1-9]{digit}*
var		{letter}({letter}|{digit}|_)*
id		({var}|$)
int		(0|{number})
float	[0-9]+(\.){digit}+
string	(\"[^\"\n]*\")
pair	(\[" "*({int}|{float})" "*," "*({int}|{float})" "*\])
degree	(\[" "*({int}|{float})" "*\])
attr	("filename"|"pathname"|"extension"|"width"|"height")

%%
"//"		{BEGIN(LINECOMMENT);}
<LINECOMMENT>\n			{BEGIN(INITIAL); yycolumn = 1;}
<LINECOMMENT>[ \t]+		{/* do nothing */}
<LINECOMMENT>.			{/* do nothing */}

"/*"		{BEGIN(BLOCKCOMMENT);}
<BLOCKCOMMENT>"*/"		{BEGIN(INITIAL);}
<BLOCKCOMMENT>\"		{BEGIN(QUOTE);}
<BLOCKCOMMENT>[ \n\t]+	{yycolumn = 1;}
<BLOCKCOMMENT>.			{/* do nothing */}
<QUOTE>\"				{BEGIN(BLOCKCOMMENT);}
<QUOTE>[ \n\t]+			{yycolumn = 1;}
<QUOTE>.				{/* do nothing */}


"BEGIN"		{return(BEGIN_SIGN);}
"END"		{return(END_SIGN);}
"bool"		{return(T_BOOL);}
"int"		{return(T_INT);}
"float"		{return(T_FLOAT);}
"string"	{return(T_STRING);}
"pair"		{return(T_PAIR);}
"degree"	{return(T_DEGREE);}
"image"		{return(T_IMAGE);}
"if"		{return(IF);}
"else"		{return(ELSE);}
"for"		{return(FOR);}
"return"	{return(RETURN);}
"break"		{return(BREAK);}
"while"		{return(WHILE);}
"void"		{return(T_VOID);}
"true"		{return(TRUE_OP);}
"false"		{return(FALSE_OP);}
"null"		{return(NULL_OP);}

{int}		{yylval=strdup(yytext); return(INT_CONST);}
{float}		{yylval=strdup(yytext); return(FLT_CONST);}
{string}	{yylval=strdup(yytext); return(STR_CONST);}
{degree}	{yylval=strdup(yytext); return(DGR_CONST);}
{pair}		{yylval=strdup(yytext); return(PAR_CONST);}

{attr}		{yylval=strdup(yytext); return(ATTRIBUTE);}
{id}		{if (strcmp(yytext,"$")==0) {
				yylval = strdup("_dollar_sign");
			 } else yylval = strdup(yytext);
			 return(ID);
			}

"+="		{return(ADD_ASSIGN);}
"-="		{return(SUB_ASSIGN);}
"*="		{return(MUL_ASSIGN);}
"/="		{return(DIV_ASSIGN);}
"%="		{return(MOD_ASSIGN);}
"#="		{return(TRS_ASSIGN);}
"@="		{return(ROT_ASSIGN);}
"=="		{return(EQ);}
"!="		{return(NE);}
"<="		{return(LE);}
">="		{return(GE);}
"&&"		{return(AND);}
"||"		{return(OR);}
"{"			{return('{');}
"}"			{return('}');}
"("			{return('(');}
")"			{return(')');}
"["			{return('[');}
"]"			{return(']');}
"@"			{return('@');}
"+"			{return('+');}
"-"			{return('-');}
"*"			{return('*');}
"/"			{return('/');}
"%"			{return('%');}
"="			{return('=');}
"<"			{return('<');}
">"			{return('>');}
"."			{return('.');}
","			{return(',');}
";"			{return(';');}
"#"			{return('#');}
"!"			{return('!');}
":"			{return(':');}

[ \t]+		{/* do nothing */}
[\n]		{yycolumn = 1;}
.			{yyerror("");}

%%

int main(int argc, char **argv)
{
   if (argc > 1) {
   	yyin = fopen(argv[1], "r");
	cur_file = argv[1];
   	yyparse();
   }
   return ret;
}


int yyerror(char * s, ...)
{
   va_list ap;
  va_start(ap, s);

  if(yylloc.first_line)
    fprintf(stderr, "%s %d.%d-%d.%d: error: unexpected input: %s\nexit with ", yylloc.file_name, 
		yylloc.first_line, yylloc.first_column, yylloc.last_line, yylloc.last_column, yytext);
  vfprintf(stderr, s, ap);
  fprintf(stderr, "\n");
  ret = 1;
  return 0;
}

void msg(void)
{
#ifdef _WINDOWS_
	HANDLE hStdout=GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleTextAttribute(hStdout,FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_INTENSITY);
	ECHO;
	SetConsoleTextAttribute(hStdout,FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
#else
	printf("\n");
	ECHO;
#endif
}
